package com.cdg.polymeric.core.ext.collectors;

import com.cdg.polymeric.AnnotationSettingBuilder;
import com.cdg.polymeric.Collectors;
import com.cdg.polymeric.ReflectUtils;
import com.cdg.polymeric.annonation.Polymeric;
import com.cdg.polymeric.annonation.PolymericConfig;
import com.cdg.polymeric.annonation.PolymericValue;
import com.cdg.polymeric.config.AnnotationSetting;
import com.cdg.polymeric.config.ClassAnnotationProperties;
import com.cdg.polymeric.config.ClassAnnotationSetting;
import jdk.nashorn.internal.objects.NativeUint8Array;
import org.apache.ibatis.reflection.Reflector;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class PolymericClassCollector  implements Collectors {
    private Reflector reflector = null;

    public PolymericClassCollector(Reflector reflector) {
        this.reflector = reflector;
    }


    @Override
    public void collect(CopyOnWriteArrayList<AnnotationSetting> annotationSettings) {
        if (Objects.nonNull(reflector)){
            Class<?> type = reflector.getType();
            Annotation[] annotations = type.getAnnotations();
            AnnotationSettingBuilder annotationSettingBuilder = new AnnotationSettingBuilder();
            ClassAnnotationSetting classAnnotationSetting = null;

            List<AnnotationSetting> annotationSettingList = new ArrayList<>();
            LinkedList<String> fieldQuerySetting = new LinkedList<String>();
            for (Annotation annotation : annotations){

                if (annotation instanceof PolymericConfig){
                     Polymeric[] polymerics = ((PolymericConfig) annotation).sources();
                     for (Polymeric polymeric : polymerics){
                         String key = polymeric.key();
                         Class<?> feign = polymeric.feign();
                         String method = polymeric.method();
                         Class<?>[] args = polymeric.args();
                         boolean batch = polymeric.batch();
                         AnnotationSetting annotationSetting = new AnnotationSetting(key,feign,method,args,batch);
                         annotationSettingList.add(annotationSetting);
                     }

                }


                if (annotation instanceof Polymeric){
                    String key = ((Polymeric) annotation).key();
                    Class<?> feign = ((Polymeric) annotation).feign();
                    String method = ((Polymeric) annotation).method();
                    Class<?>[] args = ((Polymeric) annotation).args();
                    boolean batch = ((Polymeric) annotation).batch();
                    AnnotationSetting annotationSetting = new AnnotationSetting(key,feign,method,args,batch);
                    annotationSettingList.add(annotationSetting);


                }
            }

            List<Field> fields = ReflectUtils.findAllFields(reflector.getType());
            List<ClassAnnotationProperties> fieldSettings = Collections.synchronizedList(new ArrayList<>());
            for (Field field : fields){
                Annotation[] fieldAnnotations = field.getAnnotations();

                for (Annotation annotation : fieldAnnotations){
                    if (annotation instanceof PolymericValue){
                        String name = ((PolymericValue) annotation).name();
                        boolean enableCache = ((PolymericValue) annotation).enableCache();
                        if (enableCache){
                            ClassAnnotationProperties classAnnotationProperties = new ClassAnnotationProperties(name,enableCache);
                            fieldSettings.add(classAnnotationProperties);
                        }else {
                            ClassAnnotationProperties classAnnotationProperties = new ClassAnnotationProperties(name);
                            fieldSettings.add(classAnnotationProperties);
                        }

                    }
                }
            }

            if (annotationSettingList.size() > 0){
                for (AnnotationSetting annotationSetting : annotationSettingList){
                    classAnnotationSetting = annotationSettingBuilder.buildClassAnnotation(fieldSettings,annotationSetting);
                    annotationSettings.add(classAnnotationSetting);
                }

            }





        }

    }
}
